package com.mairuide._frame.utils.sheethandler;

import com.mairuide._frame.utils.ReflectUtils;
import com.mairuide._frame.utils.RegUtil;
import com.mairuide._frame.utils.SpringUtil;
import com.mairuide.bill.DealFlow;
import com.mairuide.bill.DealFlowService;
import com.mairuide.bill.utils.DateUtils;
import com.mairuide.exceltitle_dict.enum2.FieldTypeEnum;
import com.mairuide.exceltitle_dict.enum2.PackageNameEnum;
import com.mairuide.exceltitle_dict.pojo.ExceltitleDict;
import com.mairuide.exceltitle_dict.service.ExceltitleDictService;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
import org.apache.poi.xssf.usermodel.XSSFComment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Description
 * @auther 刘中华
 * @create 2019-04-19 17:51
 */
public class SheetHandler implements XSSFSheetXMLHandler.SheetContentsHandler {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private  AtomicInteger count = new AtomicInteger(0);
    private Map<String,Object> resultMap = new HashMap<String,Object>();  //结果MAP
    private Map<String,Object> paraMap = new HashMap<String,Object>();  //参数MAP
    private DealFlow dealFlow;
    private List<ExceltitleDict> exceltitleDictList = null;
    private Map<String,ExceltitleDict> exceltitleDictMap =new HashMap<String,ExceltitleDict>();
    private  List<DealFlow> data = new ArrayList<DealFlow>();
    private int currentRow=0; //发现到最后一个的时候，会再走一次，多插一条记录。这个标记来解决这个问题
    private int currentRow2=0;//为了只取第一排的标题。
    private String tradeDate;//日期
    private String tradeTime;//时间
    @Override
    public void startRow(int i) {
        if (i==0){
            currentRow=0;
            currentRow2=0;
        }
        currentRow2=i;
        //实例化对象
        if(i>0&&currentRow!=i) {
            if (exceltitleDictMap.size()<3) {
                return;
            }
            dealFlow = new DealFlow();
        }
    }

    @Override
    public void endRow(int i) {
        if (dealFlow!=null){
            if(StringUtils.isBlank(dealFlow.getAccountRivalCard())&&StringUtils.isNotBlank(dealFlow.getAccountRivalNumber())){
                dealFlow.setAccountRivalCard(dealFlow.getAccountRivalNumber());
            }
            if(StringUtils.isBlank(dealFlow.getAccountBodyCard())&&StringUtils.isNotBlank(dealFlow.getAccountBodyNumber())){
                dealFlow.setAccountBodyCard(dealFlow.getAccountBodyNumber());
            }
            if (dealFlow.getSign()==null){
                dealFlow.setSign(1);
            }

            int successNum = count.incrementAndGet();
            data.add(dealFlow);
            currentRow=i;
            resultMap.put("successNum",successNum);
        }
        if (data.size()>=10000){
            doSomething();
            data = new ArrayList<DealFlow>();
        }
        dealFlow=null;
        tradeDate="";
        tradeTime="";
    }

    @Override
    public void cell(String cellReference, String value, XSSFComment xssfComment) {
        List matcher = RegUtil.getMatcher("([a-zA-Z]+)", cellReference);
        String pix = matcher.get(0).toString();
        value=value.trim();
        if (StringUtils.isBlank(value)) return;
        //System.out.println(value);
        Object object = value;
        if (dealFlow==null){
            if(currentRow2!=0){
                return;
            }
            if (value!=null){
                value=value.trim();
                for (int i = 0; i < exceltitleDictList.size(); i++) {
                    String titleValues = exceltitleDictList.get(i).getTitleValues();
                    if (value.equals(titleValues)){
                        exceltitleDictMap.put(pix,exceltitleDictList.get(i));
                    }
                }
            }
        }else{
            ExceltitleDict exceltitleDict = exceltitleDictMap.get(pix);
            if (exceltitleDict!=null){
                String classField = exceltitleDict.getClassField();
                try {
                    Class aClass = FieldTypeEnum.getFieldTypeEnumByVal(exceltitleDict.getFieldType());
                    if (aClass.equals(Timestamp.class) ){
                        String titleValues = exceltitleDict.getTitleValues();
                        if (titleValues.equals("交易日期")){
                            tradeDate=value;
                        }
                        if(titleValues.equals("交易时间")&&StringUtils.isNotBlank(tradeDate)){
                            value=tradeDate+value;
                        }
                        Date d= DateUtils.getDate(value);
                        if (d==null) return;
                        object = new Timestamp( d.getTime());
                    }else if (aClass.equals(BigDecimal.class) ){
                        object=new BigDecimal(value);
                    }else if (aClass.equals(Integer.class) ){
                        if("sign".equals(classField)){
                            if ("出取1D借".contains(value)){
                                object=1;
                            }else if ("进存贷C0".contains(value)){
                                object=0;
                            }else {
                                object=0;
                            }
                        }else{
                            object=Integer.valueOf(value);
                        }
                    }
                    ReflectUtils.setValue(dealFlow,DealFlow.class,classField,aClass,object);
                } catch (NumberFormatException e) {
                    logger.info("导入报错》》》值为："+object+",字段为："+classField+",第"+currentRow+"行");
                    e.printStackTrace();
                }
            }
        }

    }

    @Override
    public void headerFooter(String text, boolean isHeader, String tagName) {
    }

    /**
     * 根据标题头返回对应的数据库的行对象
     * @param titles
     * @return
     */
    public List<ExceltitleDict> getExceltitleDictByTitleHead(){
        ExceltitleDictService exceltitleDictService = SpringUtil.getBean(ExceltitleDictService.class);
        List<ExceltitleDict> listByPackageName = exceltitleDictService.getListByPackageName(PackageNameEnum.DEALFLOW.getPackageName());
        return listByPackageName;
    }

    public void doSomething(){
        for (int i = 0; i < data.size(); i++) {
            DealFlow dealFlow = data.get(i);
            dealFlow.setUuid((String)paraMap.get("uuid"));
            dealFlow.setCasemanageId((String)paraMap.get("uid"));
            dealFlow.setCreateId((Integer) paraMap.get("platManagerId"));
            dealFlow.setCreateTime(new Timestamp(System.currentTimeMillis()));
            dealFlow.setIsDelete(0);
            if(StringUtils.isEmpty(dealFlow.getAccountBodyCard()) && StringUtils.isEmpty(dealFlow.getAccountBodyNumber())) {
            	data.remove(dealFlow);
            }
        }
        DealFlowService dealFlowService = SpringUtil.getBean(DealFlowService.class);
        dealFlowService.batchSave(data);
    }

    public Map<String, Object> getResultMap() {
        return resultMap;
    }

    public void setResultMap(Map<String, Object> resultMap) {
        this.resultMap = resultMap;
    }


    public List<ExceltitleDict> getExceltitleDictList() {
        return exceltitleDictList;
    }

    public void setExceltitleDictList(List<ExceltitleDict> exceltitleDictList) {
        this.exceltitleDictList = exceltitleDictList;
    }

    public Map<String, ExceltitleDict> getExceltitleDictMap() {
        return exceltitleDictMap;
    }

    public void setExceltitleDictMap(Map<String, ExceltitleDict> exceltitleDictMap) {
        this.exceltitleDictMap = exceltitleDictMap;
    }

    public AtomicInteger getCount() {
        return count;
    }

    public void setCount(AtomicInteger count) {
        this.count = count;
    }

    public Map<String, Object> getParaMap() {
        return paraMap;
    }

    public void setParaMap(Map<String, Object> paraMap) {
        this.paraMap = paraMap;
    }

    public List<DealFlow> getData() {
        return data;
    }

    public void setData(List<DealFlow> data) {
        this.data = data;
    }
}
